#pragma once
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>

const int default_id = -1;
const int size = 4096;
const std::string default_path = ".";
const int proj_id = 0x62; // 如果创建失败修改一下
class Share_Mem
{
public:
    Share_Mem() : _shmid(default_id), _size(size) {}
    ~Share_Mem()
    {
    }
    // 创建一个全新的共享内存
    bool create()
    {
        key_t key = ftok(default_path.c_str(), proj_id);
        if (key < 0)
        {
            std::cerr << "ftok error" << std::endl;
            return false;
        }
        _shmid = shmget(key, _size, IPC_CREAT | IPC_EXCL | 0666);
        if (_shmid < 0)
        {
            std::cerr << "shmget error" << std::endl;
            return false;
        }
        std::cout << "key is " << key << "create success , shmid : " << _shmid << std::endl;
        return true;
    }
    void Getmemory()
    {
        key_t key = ftok(default_path.c_str(), proj_id);
        if (key < 0)
        {
            std::cerr << "ftok error" << std::endl;
            return;
        }
        printf("key is 0x%x\n", key);
        _shmid = shmget(key, _size, IPC_CREAT);
        if (_shmid < 0)
        {
            std::cerr << "shmget error" << std::endl;
            return;
        }
        std::cout << "key is " << key << "get success , shmid : " << _shmid << std::endl;
        return;
    }
    void Destory()
    {
        if (_shmid == default_id)
        {
            std::cerr << "shmid is invalid" << std::endl;
            return;
        }
        int ret = shmctl(_shmid, IPC_RMID, nullptr);
        if (ret < 0)
        {
            std::cerr << "shmctl error" << std::endl;
            return;
        }
        std::cout << "shmctl success" << std::endl;
        _shmid = default_id;
    }
    void Attch()
    {
        _start_memory = shmat(_shmid, nullptr, 0);
        if (_start_memory == (void *)-1)
        {
            std::cerr << "attch error" << std::endl;
            return;
        }
        std::cout << "attch success" << std::endl;
    }
    void *Virtual_address()
    {
        printf("Virtual address : %p\n", _start_memory);
        return _start_memory;
    }

private:
    int _size;
    int _shmid;
    void *_start_memory;
};